
#include "XMLTree.h"
#include "Common/Strings.h"


using namespace std;
using namespace ttg::math;
using namespace ttg::structures;
using namespace ttg::extras;

//---------------
//--- XMLTree ---
//---------------

bool XMLTree::isExplorer()
{
	return isexplorer;
}

void XMLTree::addExplorer(XMLTree *tree)
{
	explorers.push_back(tree);
}

void XMLTree::removeExplorer(XMLTree *tree)
{
	explorers.remove(tree);
}

list<XMLTree *> *XMLTree::getExplorers()
{
	return &explorers;
}

XMLTree::XMLTree(const char *name, list<XMLTree *> *explorers)
	:NamedObject(name)
{
	this->explorers = *explorers;
	this->isexplorer = true;
}

XMLTree::XMLTree(const char *name)
	:NamedObject(name)
{
	this->isexplorer = false;
}

bool XMLTree::getIntAttribute(const char *attr, int &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	string cleared = strings::clearStartEndSpaces(v);
	if (sscanf_s(v, "%d", &val) == 0)
		return false;
	return true;
}

bool XMLTree::getDWORDAttribute(const char *attr, DWORD &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	if (sscanf_s(v, "%ld", &val) == 0)
		return false;
	return true;
}

bool XMLTree::getFloatAttribute(const char *attr, float &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	if (sscanf_s(v, "%f", &val) == 0)
		return false;
	return true;
}

bool XMLTree::getDoubleAttribute(const char *attr, double &val)
{
	float t;
	bool res = this->getFloatAttribute(attr, t);
	val = t;
	return res;
}

bool XMLTree::getBoolAttribute(const char *attr, bool &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	string cleared = strings::clearStartEndSpaces(v);
	if ((cleared == "TRUE") || (cleared == "true"))
	{
		val = true;
		return true;
	} else
	if ((cleared == "FALSE") || (cleared == "false"))
	{
		val = false;
		return true;
	}
	return false;
}

bool XMLTree::getVec3fAttribute(const char *attr, vec3f &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	if (sscanf_s(v, " (%f,%f,%f)", &val.x, &val.y, &val.z) != 3)
		return false;
	return true;
}

bool XMLTree::getCol4fAttribute(const char *attr, col4f &val)
{
	const char *v;
	if (!this->getStringAttribute(attr, v))
		return false;
	if (sscanf_s(v, " (%f,%f,%f,%f)", &val.r, &val.g, &val.b, &val.a) != 4)
		return false;
	return true;
}

void XMLTree::addIntAttribute(const char *attr, int val)
{
	char str[100];
	_snprintf_s(str, 100, "%d", val);
	this->addStringAttribute(attr, str);
}

void XMLTree::addDWORDAttribute(const char *attr, DWORD val)
{
	char str[100];
	_snprintf_s(str, 100, "%ld", val);
	this->addStringAttribute(attr, str);
}

void XMLTree::addFloatAttribute(const char *attr, float val)
{
	char str[100];
	_snprintf_s(str, 100, "%f", val);
	this->addStringAttribute(attr, str);
}

void XMLTree::addDoubleAttribute(const char *attr, double val)
{
	this->addFloatAttribute(attr, (float)val);
}

void XMLTree::addBoolAttribute(const char *attr, bool val)
{
	this->addStringAttribute(attr, val ? "true" : "false");
}

void XMLTree::addVec3fAttribute(const char *attr, const vec3f &val)
{
	char str[100];
	_snprintf_s(str, 100, "(%f, %f, %f)", val.x, val.y, val.z);
	this->addStringAttribute(attr, str);
}

void XMLTree::addCol4fAttribute(const char *attr, const col4f &val)
{
	char str[100];
	_snprintf_s(str, 100, "(%f, %f, %f, %f)", val.r, val.g, val.b, val.a);
	this->addStringAttribute(attr, str);
}

XMLTree::~XMLTree()
{
	if (isexplorer)
		removeExplorer(this);
	else
	{
		list<XMLTree *>::iterator it = explorers.begin();
		while (it != explorers.end())
			if (*it != NULL)
				delete *(it++);
		explorers.clear();
	}
}